%%%-------------------------------------------------------------------
%%% File    : p10.erl
%%% Author  : Plamen Dragozov <plamen at dragozov.com>
%%% Description :
%%% The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
%%% Find the sum of all the primes below two million. 
%%%
%%% Created :  2 Dec 2008
%%%-------------------------------------------------------------------
-module(p10).

-export([solution/1]).

%%====================================================================
%% API
%%====================================================================
%%--------------------------------------------------------------------
%% Function: solution(N) -> int()
%% Description:Returns the sum of the primes bellow N
%%--------------------------------------------------------------------
solution(N) ->
    prime(3, N, math:sqrt(N), 2, [2]).

prime(N, Max, _, Sum, _) when N >= Max -> Sum; 
prime(N, Max, SqrtMax,Sum, Primes) ->
    case is_prime(N, math:sqrt(N), Primes) of 
        true -> 
            case N < SqrtMax of
                true ->  
                    %keep it for testing later numbers for primality
                    prime(N + 2, Max, SqrtMax, Sum + N, Primes++[N]);
                _ -> 
                    %no need to use for further tests, so we won't keep it
                    prime(N + 2, Max, SqrtMax, Sum + N, Primes)
            end;
        _ -> prime(N + 2, Max, SqrtMax,Sum, Primes)
    end.


%%====================================================================
%% Internal functions
%%====================================================================
%Check if a number is prime by testing against all previous primes.
is_prime(_, _, []) -> true;
is_prime(N, Sqrt, [H|T]) ->
    case (H > Sqrt) of
        true -> true;
        _ -> (N rem H =/= 0) andalso is_prime(N, Sqrt, T)
    end.
